/**
 * Background Script 消息处理器
 * 定义所有消息类型的处理逻辑
 */

import { MessageRouter, MessageSender } from "@utils/messaging";
import { StorageService } from "./services/StorageService";
import { TabService } from "./services/TabService";
import { ConfigManager } from "./services/ConfigService";
import {
  MessageType,
  TabInfoResponse,
  BaseResponse,
  SaveDataRequest,
  DataResponse,
  GetDataRequest,
  ShowNotificationRequest,
  CountElementsRequest,
  CountElementsResponse,
  InjectCSSRequest,
} from "@utils/types";

/**
 * 设置所有消息处理器
 */
export function setupMessageHandlers(
  messageRouter: MessageRouter,
  storageService: StorageService,
  tabService: TabService,
  configManager: ConfigManager
) {
  // 标签页相关消息处理
  setupTabHandlers(messageRouter, tabService);

  // 数据存储相关消息处理
  setupStorageHandlers(messageRouter, storageService);

  // 配置相关消息处理
  setupConfigHandlers(messageRouter, configManager);

  // 通知相关消息处理
  setupNotificationHandlers(messageRouter);

  // Content Script 相关消息处理
  setupContentHandlers(messageRouter, tabService);
}

/**
 * 标签页相关消息处理器
 */
function setupTabHandlers(messageRouter: MessageRouter, tabService: TabService) {
  messageRouter.register(MessageType.GET_TAB_INFO, async (): Promise<TabInfoResponse> => {
    const tabInfo = await tabService.getCurrentTab();
    return {
      success: true,
      tabInfo: tabInfo || undefined,
      timestamp: Date.now(),
    };
  });

  messageRouter.register(MessageType.GET_ALL_TABS, async (): Promise<TabInfoResponse> => {
    const allTabs = await tabService.getAllTabs();
    return {
      success: true,
      allTabs,
      timestamp: Date.now(),
    };
  });
}

/**
 * 数据存储相关消息处理器
 */
function setupStorageHandlers(messageRouter: MessageRouter, storageService: StorageService) {
  messageRouter.register(MessageType.SAVE_DATA, async (message: SaveDataRequest): Promise<BaseResponse> => {
    await storageService.save(message.key, message.data);
    return {
      success: true,
      timestamp: Date.now(),
    };
  });

  messageRouter.register(MessageType.GET_DATA, async (message: GetDataRequest): Promise<DataResponse> => {
    const data = message.key ? await storageService.get(message.key) : await storageService.getAll();

    return {
      success: true,
      data,
      key: message.key,
      timestamp: Date.now(),
    };
  });

  messageRouter.register(MessageType.DELETE_DATA, async (message: SaveDataRequest): Promise<BaseResponse> => {
    await storageService.delete(message.key);
    return {
      success: true,
      timestamp: Date.now(),
    };
  });

  messageRouter.register(MessageType.CLEAR_ALL_DATA, async (): Promise<BaseResponse> => {
    await storageService.clear();
    return {
      success: true,
      timestamp: Date.now(),
    };
  });
}

/**
 * 配置相关消息处理器
 */
function setupConfigHandlers(messageRouter: MessageRouter, configManager: ConfigManager) {
  messageRouter.register(MessageType.GET_CONFIG, async (): Promise<DataResponse> => {
    const config = await configManager.getConfig();
    return {
      success: true,
      data: config,
      timestamp: Date.now(),
    };
  });

  messageRouter.register(MessageType.UPDATE_CONFIG, async (message: SaveDataRequest): Promise<DataResponse> => {
    await configManager.updateConfig(message.data);
    const config = await configManager.getConfig();
    return {
      success: true,
      data: config,
      timestamp: Date.now(),
    };
  });
}

/**
 * 通知相关消息处理器
 */
function setupNotificationHandlers(messageRouter: MessageRouter) {
  messageRouter.register(
    MessageType.SHOW_NOTIFICATION,
    async (message: ShowNotificationRequest): Promise<BaseResponse> => {
      try {
        await browser.notifications.create({
          type: message.notificationType || "basic",
          iconUrl: "/icon/48.png",
          title: message.title,
          message: message.message,
        });

        return {
          success: true,
          timestamp: Date.now(),
        };
      } catch (error) {
        console.error("Failed to show notification:", error);
        return {
          success: false,
          error: "Failed to show notification",
          timestamp: Date.now(),
        };
      }
    }
  );
}

/**
 * Content Script 相关消息处理器
 */
function setupContentHandlers(messageRouter: MessageRouter, tabService: TabService) {
  // 判断标签页 URL 是否允许注入/通信（避免 chrome:// 等受限页面）
  const isUrlScriptable = (url?: string): boolean => {
    if (!url) return false;
    const lower = url.toLowerCase();
    const restricted = [
      "chrome://",
      "chrome-extension://",
      "moz-extension://",
      "edge://",
      "about:",
      "file://",
      "data:",
    ];
    return !restricted.some((p) => lower.startsWith(p));
  };

  // 判断是否属于 manifest 中声明的 content script 匹配域（这里使用简单域名判断）
  const isUrlSupportedByContent = (url?: string): boolean => {
    if (!url) return false;
    try {
      const host = new URL(url).hostname;
      return host.endsWith("xiaohongshu.com");
    } catch {
      return false;
    }
  };

  messageRouter.register(MessageType.HIGHLIGHT_LINKS, async (): Promise<BaseResponse> => {
    try {
      const currentTab = await tabService.getCurrentTab();
      if (currentTab?.id && isUrlScriptable(currentTab.url) && isUrlSupportedByContent(currentTab.url)) {
        await MessageSender.sendToContent(currentTab.id, {
          type: MessageType.HIGHLIGHT_LINKS,
        });
      }

      return {
        success: true,
        timestamp: Date.now(),
      };
    } catch (error) {
      return {
        success: false,
        error: "Failed to highlight links",
        timestamp: Date.now(),
      };
    }
  });

  messageRouter.register(
    MessageType.COUNT_ELEMENTS,
    async (message: CountElementsRequest): Promise<CountElementsResponse> => {
      try {
        const currentTab = await tabService.getCurrentTab();
        if (currentTab?.id && isUrlScriptable(currentTab.url) && isUrlSupportedByContent(currentTab.url)) {
          const response = await MessageSender.sendToContent(currentTab.id, message);
          return response as CountElementsResponse;
        }

        return {
          success: false,
          count: 0,
          selector: message.selector,
          error: "No eligible active tab found",
          timestamp: Date.now(),
        };
      } catch (error) {
        return {
          success: false,
          count: 0,
          selector: message.selector,
          error: "Failed to count elements",
          timestamp: Date.now(),
        };
      }
    }
  );

  messageRouter.register(MessageType.INJECT_CSS, async (message: InjectCSSRequest): Promise<BaseResponse> => {
    try {
      const currentTab = await tabService.getCurrentTab();
      if (currentTab?.id && isUrlScriptable(currentTab.url) && isUrlSupportedByContent(currentTab.url)) {
        await browser.scripting.insertCSS({
          target: { tabId: currentTab.id },
          css: message.css,
        });
      }

      return {
        success: true,
        timestamp: Date.now(),
      };
    } catch (error) {
      return {
        success: false,
        error: "Failed to inject CSS",
        timestamp: Date.now(),
      };
    }
  });
}
